using System;
using UnityEngine;
using Puerts;

namespace lion {
    public class JsLancher : MonoBehaviour {
        public delegate void JsMain(JsLancher instance);
        public static string module;
        private JsEnv jsEnv = Main.jsEnv;

        #if UNITY_EDITOR
            [ReadOnly]
            public string modulePath; 
        #endif                      

        public Action JsAwake;
        public Action JsStart;
        public Action<float> JsFixUpdate;
        public Action<float> JsUpdate;
        public Action<float> JsLateUpdate;
        public Action JsFinalize;
        
        /// <summary>
        /// 创建 Js 组件挂载
        /// </summary>
        /// <param name="gameObject">需要挂载的游戏对象</param>
        /// <param name="module">js 模块路径</param>
        /// <returns>JsLancher</returns>
        public static JsLancher CreateLancher(GameObject gameObject, string module){
            JsLancher.module = module;
            JsLancher jsLancher = gameObject.AddComponent<JsLancher>();
            #if UNITY_EDITOR
                jsLancher.modulePath = module;
            #endif
            JsLancher.module = null;
            return jsLancher;
        }
        
        void Awake(){
            string jsCode = "require('"+module+"').default;";
            string jsDebugPath = Main.jsLoader.GetScriptDebugPath(module);
            JsMain jsMain = jsEnv.Eval<JsMain>(jsCode,jsDebugPath);
            if(jsMain != null) jsMain(this);             // 运行 Js 导出的方法
            if(JsAwake != null) JsAwake();
        }
        
        void Start(){
            if(JsStart != null) JsStart();
        }

        void FixUpdate(){
            if(JsFixUpdate != null) JsFixUpdate(Time.fixedUnscaledDeltaTime);
        }

        void Update(){
            if(jsEnv != null) jsEnv.Tick();
            if(JsUpdate != null) JsUpdate(Time.unscaledDeltaTime);
        }

        void LateUpdate(){
            if(JsLateUpdate != null) JsLateUpdate(Time.unscaledDeltaTime); 
        }

        void OnDestroy() {
            if(JsFinalize != null) JsFinalize();        // 释放内存
            if(jsEnv != null) jsEnv.Dispose();          // 销毁虚拟机
            JsAwake = null;
            JsStart = null;
            JsFixUpdate = null;
            JsUpdate = null;
            JsLateUpdate = null;
            JsFinalize = null;
        }
    }
}